package com.wxtech.heartbeat.server.protocol;

import java.sql.SQLException;

import org.apache.log4j.Logger;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.wxtech.heartbeat.Context;
import com.wxtech.heartbeat.database.DataManager;
import com.wxtech.heartbeat.model.DataCollect;
import com.wxtech.heartbeat.model.Device;
import com.wxtech.heartbeat.model.ErrorData;
///import com.wxtech.heartbeat.model.HeartBeat;
import com.wxtech.heartbeat.util.RedisUtil;

import io.netty.channel.ChannelHandlerContext;

public class DataCollectProtocolDecodeResult extends DecodeResult {
	private static Logger logger = Logger.getLogger(DataCollectProtocolDecodeResult.class);
	//解析好的model对象
	private ErrorData errorData;
	private Device device;
	private DataCollect dataCollect;
	private boolean isValid;

	public DataCollectProtocolDecodeResult() {
		// TODO Auto-generated constructor stub
	}
	
	public static Logger getLogger() {
		return logger;
	}

	public static void setLogger(Logger logger) {
		DataCollectProtocolDecodeResult.logger = logger;
	}

	public ErrorData getErrorData() {
		return errorData;
	}

	public void setErrorData(ErrorData errorData) {
		this.errorData = errorData;
	}

	public Device getDevice() {
		return device;
	}

	public void setDevice(Device device) {
		this.device = device;
	}

	public DataCollect getDataCollect() {
		return dataCollect;
	}

	public void setDataCollect(DataCollect dataCollect) {
		this.dataCollect = dataCollect;
	}

	public boolean isValid() {
		return isValid;
	}

	public void setValid(boolean isValid) {
		this.isValid = isValid;
	}


	@Override
	public void handler(ChannelHandlerContext ctx) {
		// TODO Auto-generated method stub
//在这里直接处理，比如保存数据，或者保存device等等
		//甚至给客户端返回数据等等
		try {
			processBusinessLogic(this);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
//			e.printStackTrace();
			logger.error(e.getMessage(), e);
			throw new RuntimeException(e);
		}
	}
	
	
	private String dataCollectToJson(DataCollect dc, long dbPk) {
		String ret = String.format(
				"{" +
				"\"db_pk\" : \"%d\", " +
				"\"msg_code\" : \"%d\", " +
				"\"total\" : \"%d\", " +
				"\"id\" : \"%d\", " +
				"\"device_id\" : \"%s\", " +
				"\"timestamp\" : \"%d-%02d-%02d %02d:%02d:%02d\", " + 
				"\"uvol_total\" : \"%f\", " +
				"\"cvol_total\" : \"%f\", " +
				"\"temp\" : \"%f\", " +
				"\"pressure\" : \"%f\", " +
				"\"snra1\" : \"%d\", " +
				"\"snrb1\" : \"%d\"," +
				"\"snra2\" : \"%d\", " +
				"\"snrb2\" : \"%d\"," +
				"\"snra3\" : \"%d\", " +
				"\"snrb3\" : \"%d\", " +
				"\"agc_level_a1\" : \"%d\", " +
				"\"agc_level_b1\" : \"%d\", " +
				"\"agc_level_a2\" : \"%d\", " +
				"\"agc_level_b2\" : \"%d\", " +
				"\"agc_level_a3\" : \"%d\", " +
				"\"agc_level_b3\" : \"%d\", " +
				"\"sos1\" : \"%f\", " +
				"\"sos2\" : \"%f\", " +
				"\"sos3\" : \"%f\", " +
				"\"flow_vel1\" : \"%f\", " +
				"\"flow_vel2\" : \"%f\", " +
				"\"flow_vel3\" : \"%f\", " +
				"\"vol_total\" : \"%f\", " +
				"\"battery_usage\" : \"%d\"" +
				"}"
				,
				dbPk,
				dc.getMsg_id(),
				dc.getTotal(),
				dc.getBiaohao(),
				dc.getDeviceId(),
				dc.getDateTime().getYear() + 1900, 
				dc.getDateTime().getMonth() + 1, 
				dc.getDateTime().getDate(),
				dc.getDateTime().getHours(), 
				dc.getDateTime().getMinutes(), 
				dc.getDateTime().getSeconds(),
				dc.getCumulativeGongAmount(),
				dc.getCumulativeBiaoAmount(),
				dc.getTemperture(),
				dc.getPressure(),
				dc.getInterFwdChannelSNR(),
				dc.getInterRvsChannelSNR(),
				dc.getUpFwdChannelSNR(),
				dc.getUpRvsChannelSNR(),
				dc.getLowFwdChannelSNR(),
				dc.getLowRvsChannelSNR(),
				dc.getInterFwdChannelGain(),
				dc.getInterRvsChannelGain(),
				dc.getUpFwdChannelGain(),
				dc.getUpRvsChannelGain(),
				dc.getLowFwdChannelGain(),
				dc.getLowRvsChannelGain(),
				dc.getUpChannelSoundVelocity(),
				dc.getInterChannelSoundVelocity(),
				dc.getLowChannelSoundVelocity(),
				dc.getUpChannelFlowVelocity(),
				dc.getInterChannelFlowVelocity(),
				dc.getLowChannelFlowVelocity(),
				dc.getCurrentFlow(),
				dc.getBatteryStatus()
			);
		return ret;
	}
	private void processBusinessLogic(DataCollectProtocolDecodeResult protocol) throws SQLException {
		DataManager dataManager = Context.getDataManager();
		if (protocol.isValid()) {
			Device protocolDevice = protocol.getDevice();
			if (protocolDevice == null) {
				logger.error("device is null");
				return;
			}

			logger.info("check if it is a new device");
			Device device = dataManager.getDevice(protocolDevice.getDevice_id());
			if (device == null) {
				logger.info(protocolDevice.getDevice_id() + " is a new device, saving device data");
				dataManager.addDevice(protocolDevice);
			} else {
				logger.info(device.getDevice_id() + " is an existing device");
			}

			logger.info("save data collect data");
			long dbPk = 0;
			try {
				dataManager.addDataCollect(protocol.getDataCollect());
				dbPk = protocol.getDataCollect().getId();
			} catch(Exception e) {
				logger.error("save db error." + e.getMessage(),  e);
			}
			logger.info("publish to redis");
			String json = dataCollectToJson(protocol.getDataCollect(), dbPk);

			//json = Context.getObjectMapper().writeValueAsString(protocol.getDataCollect());
			//to do capsulate my own json String here include the save to db result 
			RedisUtil.getInstance().publishRedis(json);
			logger.debug("publish done...");		
		} else {
			logger.warn("data collect protocol data is invalid" + protocol.getErrorData());
			logger.info("save ErrorData");
			dataManager.addErrorData(protocol.getErrorData());
		}

	}

}
